import os
import threading
import time
import hashlib
from flask import Flask, request, make_response, Blueprint
import xml.etree.ElementTree as ET
import requests
import json
import requests
from app.config import exConfig

wxgzh_bp = Blueprint('wxgzh', __name__, url_prefix='/wxgzh')


def get_tenant_wechat_configs(tenant_id=None):
    """获取租户的微信配置"""
    from app.services.tenant_config_service import TenantConfigService
    from app.models.tenant_config import ConfigTypes
    from flask import g, has_request_context

    if tenant_id is None:
        # 只有在请求上下文中才尝试从g获取tenant_id
        if has_request_context():
            tenant_id = getattr(g, 'tenant_id', 1)
        else:
            tenant_id = 1  # 默认使用租户1

    # 获取公众号配置
    gzh_app_id = TenantConfigService.get_config(tenant_id, ConfigTypes.WECHAT_GZH, 'app_id')
    gzh_app_secret = TenantConfigService.get_config(tenant_id, ConfigTypes.WECHAT_GZH, 'app_secret')
    gzh_token = TenantConfigService.get_config(tenant_id, ConfigTypes.WECHAT_GZH, 'token')

    # 获取小程序配置
    mp_app_id = TenantConfigService.get_config(tenant_id, ConfigTypes.WECHAT_MP, 'app_id')

    # 兜底使用环境变量
    if not gzh_app_id:
        gzh_app_id = os.environ.get('GMINIPROGRAM_APPID', 'wx234b2bfe09e3272d')
    if not gzh_app_secret:
        gzh_app_secret = os.environ.get('GMINIPROGRAM_SECRET', '9d84ec647d1e4ca273eaeed383b40319')
    if not gzh_token:
        gzh_token = os.environ.get('WECHAT_TOKEN', 'Eric')
    if not mp_app_id:
        mp_app_id = os.environ.get('MINIPROGRAM_APPID')

    return {
        'gzh_app_id': gzh_app_id,
        'gzh_app_secret': gzh_app_secret,
        'gzh_token': gzh_token,
        'mp_app_id': mp_app_id
    }


MEDIA_ID = None  # 图片ID
WEB_URL = 'https://jfxx.2028ka.cn/gxfjf/'


def check_signature(token, signature, timestamp, nonce):
    s = ''.join(sorted([token, timestamp, nonce]))
    sha1 = hashlib.sha1(s.encode('utf-8')).hexdigest()
    return sha1 == signature


def get_access_token(tenant_id=None):
    """获取access_token"""
    configs = get_tenant_wechat_configs(tenant_id)
    url = f"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={configs['gzh_app_id']}&secret={configs['gzh_app_secret']}"
    try:
        res = requests.get(url).json()
        print("获取 access_token 结果：", res)
        return res.get("access_token")
    except Exception as e:
        print("获取 access_token 失败：", e)
        return None


def send_image_message(openid, access_token):
    global MEDIA_ID
    url = f"https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={access_token}"
    data = {
        "touser": openid,
        "msgtype": "image",
        "image": {
            "media_id": MEDIA_ID
        }
    }
    res = requests.post(url, json=data)
    print("发送图片消息结果：", res.json())


def send_text_message(openid, access_token, content=None):
    url = f"https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={access_token}"
    headers = {"Content-Type": "application/json; charset=UTF-8"}
    content = (
        f"你好，点开下面链接直接购买次数哦，充值马上到账 马上使用！\n"
        "https://jfxx.2028ka.cn/gxfjf/\n"
        "https://jfxx.2028ka.cn/gxfjf/"
    )
    data = {
        "touser": openid,
        "msgtype": "text",
        "text": {
            "content": content  # 👈 是 str，不是 json.dumps(content)
        }
    }

    body = json.dumps(data, ensure_ascii=False)  # ✅ 中文不转义
    requests.post(url, data=body.encode("utf-8"), headers=headers)


def send_news_message(openid, access_token):
    url = f"https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={access_token}"
    data = {
        "touser": openid,
        "msgtype": "news",
        "news": {
            "articles": [
                {
                    "title": "次数充值.拍照次数.点击进入",
                    "description": "秒通车服·搜题神器拍照搜索·准确度99.9%点击增加拍照搜题次数",
                    "url": WEB_URL,
                    "picurl": "https://wx.qlogo.cn/mmhead/j8cooK2zCqrQRcicVO2IjAFLvia3btwR5mTOz6w6u3Sl8bZVMCYr9kB7KHDEYpZ8RDa6KEUMDce0Y/0"
                }
            ]
        }
    }
    headers = {"Content-Type": "application/json; charset=UTF-8"}
    try:
        body = json.dumps(data, ensure_ascii=False)  # ✅ 中文不转义
        result = requests.post(url, data=body.encode("utf-8"), headers=headers)
        print("发送图文客服消息结果:", result)
        return result
    except Exception as e:
        print("发送图文客服消息异常:", e)
        return None


@wxgzh_bp.route('/wechat', methods=['GET', 'POST'])
def wechat():
    signature = request.args.get('signature')
    timestamp = request.args.get('timestamp')
    nonce = request.args.get('nonce')

    # 获取租户配置
    configs = get_tenant_wechat_configs()
    wechat_token = configs['gzh_token']

    if not check_signature(wechat_token, signature, timestamp, nonce):
        return "签名验证失败", 403

    if request.method == 'GET':
        echostr = request.args.get('echostr')
        return echostr or ""

    if request.method == 'POST':
        xml_data = request.data
        xml = ET.fromstring(xml_data)

        msg_type = xml.find("MsgType").text
        from_user = xml.find("FromUserName").text
        to_user = xml.find("ToUserName").text
        event = xml.find("Event").text if xml.find("Event") is not None else None
        event_key = xml.find("EventKey").text if xml.find("EventKey") is not None else None

        if msg_type == 'event' and event == 'subscribe':
            send_text_message(from_user, get_access_token())

            def send_news_kf_message():
                access_token = get_access_token()
                if access_token:
                    send_news_message(from_user, access_token)

            threading.Thread(target=send_news_kf_message).start()

        if msg_type == 'event' and event == 'CLICK':
            print("用户点击了菜单，EventKey:", event_key)
            if event_key == "menu_customer_service":
                access_token = get_access_token()
                if access_token:
                    send_image_message(from_user, access_token)
            return make_response("")

        # 这里只对文本消息做回复，其他消息类型可以扩展
        if msg_type == 'text':
            send_text_message(from_user, get_access_token())

            def send_news_kf_message():
                access_token = get_access_token()
                if access_token:
                    send_news_message(from_user, access_token)

            threading.Thread(target=send_news_kf_message).start()

            def send_images_message():
                access_token = get_access_token()
                if access_token:
                    send_image_message(from_user, get_access_token(),
                                       '0RCvDvSibHKtA5LSdqSrtoKpAbuWZVJ2ewp1jCwUndYXOOjMpd5_GuTAXcfSxJrV')

            threading.Thread(target=send_images_message).start()
        return "success"


def upload_temp_image(filepath, access_token):
    url = f"https://api.weixin.qq.com/cgi-bin/media/upload?access_token={access_token}&type=image"
    with open(filepath, 'rb') as f:
        files = {'media': f}
        response = requests.post(url, files=files)
        result = response.json()
        print("上传图片接口返回：", result)
        # 返回的字典里有 media_id 字段
        return result.get('media_id')


def create_menu(access_token, tenant_id=None):
    """创建微信公众号菜单"""
    url = f"https://api.weixin.qq.com/cgi-bin/menu/create?access_token={access_token}"

    # 获取租户配置
    configs = get_tenant_wechat_configs(tenant_id)
    miniprogram_appid = configs['mp_app_id']

    menu_data = {
        "button": [
            {
                "name": "学法减分",
                "sub_button": [
                    {
                        "type": "miniprogram",
                        "name": "学法减分",
                        "appid": miniprogram_appid,
                        "pagepath": "pages/index/index"
                    },
                    {
                        "type": "miniprogram",
                        "name": "拍照搜题",
                        "appid": miniprogram_appid,
                        "pagepath": "pages/index/index"
                    }
                ]
            },
            {
                "type": "view",
                "name": "次数充值",
                "url": WEB_URL
            },
            {
                "type": "click",
                "name": "人工客服",
                "key": "menu_customer_service"
            }
        ]
    }

    headers = {
        "Content-Type": "application/json; charset=UTF-8"
    }

    # 使用 json.dumps + ensure_ascii=False，防止中文变 \uXXXX
    payload = json.dumps(menu_data, ensure_ascii=False).encode("utf-8")

    try:
        res = requests.post(url, data=payload, headers=headers)
        print("创建菜单结果:", res.json())
        return res.json()
    except Exception as e:
        print("创建菜单失败:", e)
        return {"errcode": -1, "errmsg": str(e)}


def init_app(app: Flask):
    """初始化微信公众号应用"""
    # 在应用初始化时不执行需要上下文的操作
    # 这些操作应该在实际请求时执行
    with app.app_context():
        try:
            # 使用默认租户配置初始化
            token = get_access_token(tenant_id=1)  # 使用默认租户
            if token:
                create_menu(token, tenant_id=1)
                app.logger.info("微信公众号菜单初始化成功")
            else:
                app.logger.warning("微信公众号token获取失败，跳过菜单初始化")
        except Exception as e:
            app.logger.error(f"微信公众号初始化失败: {str(e)}")

    global MEDIA_ID
    # if not MEDIA_ID:
    #     access_token = get_access_token()
    #     media_id = upload_temp_image('/www/wwwroot/service.jpg', access_token)
    #     if media_id:
    #         MEDIA_ID = media_id
    #     print("拿到的 media_id 是：", media_id)
